﻿using System;
using System.Collections.Generic;
using System.Text;
using IntelligentDecisioning.SharePoint.Definition;
using System.Reflection;
using Microsoft.SharePoint;
using IntelligentDecisioning.SharePoint.Definition.Fields;
using IntelligentDecisioning.SharePoint.Definitions;
using Microsoft.Practices.SPG.Common.ServiceLocation;
using IntelligentDecisioning.SharePoint.Repositories;
using System.Security.Permissions;
using Microsoft.SharePoint.Security;
using NIHR.RDMIS.StudyCore.Feature.SharePoint.Definitions.Lists;

namespace IntelligentDecisioning.SharePoint.FeatureReceivers
{
    /// <summary>
    /// This demonstration feature receiver is designed to illustrate
    /// how to use the id-sharepoint framework to provision various sharepoint
    /// artifacts.
    /// 
    /// In order to use the id-sharepoint framework our feature receiver must extend the base
    /// feature reciver class IDBaseFeatureReceiver
    /// </summary>
    [SharePointPermissionAttribute(SecurityAction.Demand, ObjectModel = true)]
    public class DemoFeatureReceiver: IDBaseFeatureReceiver
    {
        #region Override Define Feature Properties to specify the artifacts we want to provision using id-sharepoint

        /// <summary>
        /// We override the define feature properties method to indicate to the id-sharepoint
        /// framework which sharepoint artifacts we want to provision.
        /// 
        /// There are a set of boolean flags in the base class. For each type of artifact that
        /// needs to be configured, set the flag to true.
        /// 
        /// In this feature we set all the flags to true as we are demonstrating provisioning of 
        /// each type of sharepoint artifact currently supported by our framework. However in
        /// you custom features, ony set the flags for the artifacts you need (all flags are
        /// defaulted to false)
        /// 
        /// Each flag is paired with a corresponding "GetConfiguration" method that must also
        /// be overrriden to provide the definition of the item to be provisioned
        /// 
        /// i.e. To provision one or more custom lists there are two steps to take:
        /// 
        ///  - Set HastLists = true; in the DefineFeatureProperties method
        ///  - Override GetLists() to return a list if SharePointList objects
        ///  which define the properties of the lists to be provisioned
        /// </summary>
        protected override void DefineFeatureProperties()
        {
            // We are provisioning one or more security groups
            base.HasSecurityGroups = true; 

            // We are provisioning one or more site columns
            base.HasSiteColumns = true;

            // We are provisioining one or more content types
            base.HasContentTypes = true;


            base.HasLists = true; // We are provisioning one or more sharepoint lists
            base.HasEventHandlers = true; // We are registering one or more event receivers 
            base.HasContentTypes = true; // We are provisioning one or more custom content types
            base.HasWorkflows = true; // We are provisioning on or more custom workflows
        }

        #endregion
        
        #region Define the sharepoint artifacts (Lists, site columns event receivers etc) that we want to provision


        #region Override Get Groups to define the custom security groups we need to create

        protected override List<SecurityGroup> GetCustomGroups()
        {
            List<SecurityGroup> exampleGroups = base.GetCustomGroups(); // We use the empty list created in the base class for convenience

            // First we define a new group to be added to the current site collection
            SecurityGroup demoAdminGroup = new SecurityGroup("Demo Admins", "id-sharepoint demo admins", Scope.RootSite);
            exampleGroups.Add(demoAdminGroup);
            exampleGroups.Add(demoAdminGroup); // we add the group twice to illustrate that it will ony be provisioned once

            // The a second group to be created only in the scope of the current site
            SecurityGroup demoCurrentSiteGroup = new SecurityGroup("Demo Current Site Group", "id-sharepoint demo current site group", Scope.CurrentSite);
            exampleGroups.Add(demoCurrentSiteGroup);

            return exampleGroups;
        }

        #endregion

        #region Override Get SiteColumns to define the site columns that we need to create

        protected override List<Field> GetSiteColumns()
        {
            List<Field> exampleSiteColumns = base.GetSiteColumns();

            // We treat site columns as simply fields that are created either at the site or site collection level



            RichTextField exampleSiteColumn = new RichTextField();
            exampleSiteColumn.Id = "FD45D098-7B16-41a0-ADFB-596C544900C0";
            exampleSiteColumn.GroupName = "Intelligent Decisioning Ltd";
            exampleSiteColumn.Name = "demoRichTextField";
            exampleSiteColumn.DisplayName = "My demonstration rich text field";
            exampleSiteColumn.AuthoringInfo = "This is an example rich text field";
            exampleSiteColumn.IsSiteColumn = true;
            exampleSiteColumn.SiteColumnScope = Scope.SiteCollection;
            exampleSiteColumn.Mode = RichTextMode.FullHtml;
            exampleSiteColumns.Add(exampleSiteColumn);

            return exampleSiteColumns;
        }

        #endregion

        #region Override GetContentTypes() to define the content types that we need to create

        protected override List<ContentType> GetContentTypes()
        {
            List<ContentType> exampleContentTypes =  base.GetContentTypes();

            ContentType exampleContentType = new ContentType();
         //   exampleContentType.baseType = ContentBaseType.

            return exampleContentTypes;
        }

        #endregion

        #region Override Get Lists to define the custom lists we need to create

        /// <summary>
        /// Returns the details of the sharepoint lists that we wish to provision. 
        /// 
        /// We have created a hierachy of definition objects to store the properties
        /// that we nned to provision the lists and their columns. This allows us 
        /// to gain a level of indirection for the underlying sharepoint object 
        /// model (protecting us from future changes) and allows us to define our lists
        /// in a more intuitive way. Also, we can encapsulate our custom list definitions
        /// by extending the SharePointList class. This allows us to create a library
        /// of predefined ad test list components that we can then easily resuse across
        /// many sharepoint projects.
        /// 
        /// </summary>
        /// <returns></returns>
        protected override List<SharePointList> GetLists()
        {
            List<SharePointList> lists = base.GetLists();

            SharePointList demoList = GetTaskList();

            lists.Add(demoList);

            // And heres one we created earlier - list defintions can
            // be encapsulated in classes and reused several times
            lists.Add(new DemonstrationCustomList());
            lists.Add(new DemonstrationTaskList());
            lists.Add(new DemonstrationContactList());
            lists.Add(new DemonstrationDocumentLibraryList());
            lists.Add(new DemonstrationProjectTaskList());
            lists.Add(new DemonstrationProjectTaskExtensionList());
            lists.Add(new StudyMetadataList());
       
            return lists;

        }

        private static SharePointList GetTaskList()
        {
            SharePointList demoList = new SharePointList("Demonstration List");
            demoList.Description = "The demonstration list is a custom list that has been provisioned automatically by the id-sahrepoint code";
            demoList.OnQuickLaunch = true; // the default for this is true anyway
            demoList.OverwriteIfPresent = true;


            Field textField = new Field(); // will create a new guid automatically
            textField.Type = SPFieldType.Text.ToString();
            textField.Name = "ExampleTextField";
            textField.StaticName = "ExampleTextField";
            textField.DisplayName = "Example Text Field";
            demoList.Fields.Add(textField);

            Field dateField = new Field();
            dateField.Type = SPFieldType.DateTime.ToString();
            dateField.Name = "ExampleDateField";
            dateField.StaticName = "ExampleDateField";
            dateField.DisplayName = "Example Date Field";
            demoList.Fields.Add(dateField);

            ChoiceField choiceField = new ChoiceField();
            choiceField.Type = SPFieldType.Choice.ToString();
            choiceField.Name = "ExampleChoiceField";
            choiceField.StaticName = "ExampleChoiceField";
            choiceField.DisplayName = "Example Choice Field";
            choiceField.Choices.Add("1");
            choiceField.Choices.Add("2");
            choiceField.Choices.Add("3");
            choiceField.Format = "Dropdown";
            demoList.Fields.Add(choiceField);
            return demoList;
        }

        private static SharePointList GetContactList()
        {
            SharePointList demoList = new SharePointList("Demonstration List");
            demoList.Description = "The demonstration list is a custom list that has been provisioned automatically by the id-sahrepoint code";
            demoList.OnQuickLaunch = true; // the default for this is true anyway
            demoList.OverwriteIfPresent = true;


            Field textField = new Field(); // will create a new guid automatically
            textField.Type = SPFieldType.Text.ToString();
            textField.Name = "ExampleTextField";
            textField.StaticName = "ExampleTextField";
            textField.DisplayName = "Example Text Field";
            demoList.Fields.Add(textField);

            Field dateField = new Field();
            dateField.Type = SPFieldType.DateTime.ToString();
            dateField.Name = "ExampleDateField";
            dateField.StaticName = "ExampleDateField";
            dateField.DisplayName = "Example Date Field";
            demoList.Fields.Add(dateField);

            ChoiceField choiceField = new ChoiceField();
            choiceField.Type = SPFieldType.Choice.ToString();
            choiceField.Name = "ExampleChoiceField";
            choiceField.StaticName = "ExampleChoiceField";
            choiceField.DisplayName = "Example Choice Field";
            choiceField.Choices.Add("1");
            choiceField.Choices.Add("2");
            choiceField.Choices.Add("3");
            choiceField.Format = "Dropdown";
            demoList.Fields.Add(choiceField);
            return demoList;
        }
        #endregion

        #region Override GetListEventHandlers to add event handlers to new or existing lists

        protected override List<SharePointListItemEventHandler> GetListEventHandlers()
        {
            List<SharePointListItemEventHandler> eventHandlers =  base.GetListEventHandlers();

        //Create an event handler on the task list
            SharePointListItemEventHandler taskListEventHandler = new SharePointListItemEventHandler();
            // The name of the list we are registering on
            taskListEventHandler.ListName = "Tasks";
            taskListEventHandler.AssemblyName = Assembly.GetExecutingAssembly().FullName;
            taskListEventHandler.RegistrationType = RegistrationType.Name;
            // Add each valid action that we want the event receiver to handle
            taskListEventHandler.EventReceiverTypes.Add(SPEventReceiverType.ItemAdded);
            taskListEventHandler.EventReceiverTypes.Add(SPEventReceiverType.ItemDeleted);
            // The name of our receiver class
            taskListEventHandler.ClassName = "IntelligentDecisioning.SharePoint.Lists.EventReceivers.DemoTaskListItemEventReceiver";
            eventHandlers.Add(taskListEventHandler);
            return eventHandlers;
        }

        #endregion

        #region Override DoFeatureActivated to perfrom and custom activation tasks

        [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
        protected override void DoFeatureActivated()
        {
            base.DoFeatureActivated();

            
        }

        #endregion

        #region Do Feature Installed

        protected override void DoFeatureInstalled()
        {
            base.DoFeatureInstalled();

            ServiceLocatorConfig typeMappings = new ServiceLocatorConfig();
            typeMappings.RegisterTypeMapping<IDemonstrationTaskRepository, DemonstrationTaskRepository>();
            typeMappings.RegisterTypeMapping<IDemonstrationContactRepository, DemonstrationContactRepository>();
            typeMappings.RegisterTypeMapping<IDemonstrationDocumentLibraryRepository, DemonstrationDocumentLibraryRepository>();
            typeMappings.RegisterTypeMapping<IDemonstrationDocumentLibraryRepository, DemonstrationDocumentLibraryRepository>();
            typeMappings.RegisterTypeMapping<IDemonstrationDocumentLibraryRepository, DemonstrationDocumentLibraryRepository>();

        }

        #endregion

        #endregion
    }
}
